package ink.ykb.configurer;

import java.io.PrintWriter;
import java.util.Collections;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.web.servlet.error.AbstractErrorController;
import org.springframework.boot.web.servlet.error.DefaultErrorAttributes;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import com.fasterxml.jackson.databind.ObjectMapper;

import ink.ykb.util.CommonResult;
import ink.ykb.util.PlatformException;
import ink.ykb.util.PlatformRuntimeException;


@Controller
public class ErrorController extends AbstractErrorController{

	/**
	 * log4j 日志
	 */
	private Logger logger = LoggerFactory.getLogger(ErrorController.class);  

	public ErrorController() {
		super(new DefaultErrorAttributes());
	}
	
	@RequestMapping("/error")
	public String getErrorPath(HttpServletRequest request,HttpServletResponse response) {
		//获取异常
		Throwable cause = getCause(request);
		
		if(isJsonRequest(request,response)) {
			try {
				CommonResult result = CommonResult.resultFail(cause);
				String msg = new ObjectMapper().writeValueAsString(result);
				response.setHeader("Content-Type", "application/json;charset=utf-8");
				response.setHeader("Content-Encoding", "UTF-8");
				response.setStatus(200);
				
				PrintWriter out = response.getWriter();
				
				out.print(msg);
				out.flush();
				out.close();
			}catch (Exception e) {
				e.printStackTrace();
			}
			return null;
			
		}else {
			Map<String, Object> mode = Collections.unmodifiableMap(getErrorAttributes(request, false));
			Integer status = (Integer)mode.get("status");
			String message = (String)mode.get("message");
			//友好提示
			String errorMessage = getErrorMessage(cause);
			
			response.setStatus(status);
			
			logger.error("错误日志：状态码：{} 信息：{} 异常：",status,message, cause);
			request.setAttribute("errorMessage", errorMessage);
			request.setAttribute("status", status);
			request.setAttribute("cause", cause);
			
			return "error";
		}
	}
	
	private boolean isJsonRequest(HttpServletRequest request,HttpServletResponse response) {
	
		String requestUri = (String)request.getAttribute("javax.servlet.error.request_uri");
		
		Throwable cause = getCause(request);
		if( cause instanceof PlatformRuntimeException || cause instanceof PlatformException){
			return true;
		}
		if(requestUri != null && requestUri.endsWith(".json")) {
			return true;
		}else {
			if((request.getHeader("Accept") != null && request.getHeader("Accept").contains("application/json") )|| (response.getHeader("Content-Type") != null && response.getHeader("Content-Type").contains("application/json"))) {
				return true;
			}else {
				return false;
			}
		}
		
	}

	private String getErrorMessage(Throwable ex) {
		if(ex instanceof PlatformException || ex instanceof PlatformRuntimeException ) {
			return ex.getMessage();
		}
		return "服务器错误，请联系管理员";
	}

	private Throwable getCause(HttpServletRequest request) {
		
		Throwable error = (Throwable)request.getAttribute("javax.servlet.error.exception");
		if(error != null) {
			while(error instanceof ServletException && error.getCause() != null) {
				error = ((ServletException)error).getCause();
			}
		}
		
		return error;
	}

	@Override
	public String getErrorPath() {
		// TODO Auto-generated method stub
		return null;
	}
	
	
	
}
